import os
import yaml
from yaml import loader
from .strategy_template import StraTmpl
from .data_driven_stra_tmpl import DDStraTmpl


def load_strategy(stra_conf, engine):
    """加载../strategy目录下的策略"""
    """通过文件名取到对应的继承Data的类并实例"""
    stra_file = stra_conf.stra_file
    stra_class = stra_conf.stra_class
    if stra_file:  # in stra_conf.cfg.strategy_name
        f = os.path.join('./strategies', f'{stra_file}.py')
        # 只处理对应的 py文件
        if not os.path.exists(f):
            stra_conf.cfg.log.info(f'{f} is not exists!')
            return f'{f} is not exists!'
        # 以目录结构作为 namespace
        module_name = f"{os.path.split(os.path.dirname(f))[1]}.{stra_class}"
        module = __import__(module_name)  # import module

        c = getattr(getattr(module, stra_class), stra_class)  # 双层调用才是class,单层是为module
        if not issubclass(c, (StraTmpl, DDStraTmpl)):  # 类c是Data的子类
            return f'{stra_class} 不是策略类'

        # 与策略文件同名的 yaml 作为配置文件处理
        cfg_file = os.path.join(f'./strategies/{stra_file}.yml')
        if os.path.exists(cfg_file):
            # 清除策略信号
            if stra_conf.cfg.pg_order is not None:
                # 取旧信号最后时间
                if 'app' in os.environ:
                    sql = f'''select strategy_id, instrument, max(order_time) ot
from public.strategy_sign
where strategy_group = '{stra_file}'
group by strategy_id, instrument
'''
                    conn: Connection = stra_conf.cfg.pg_order.raw_connection()
                    cursor = conn.cursor()
                    cursor.execute(sql)
                    rows = cursor.fetchall()
                    for row in rows:
                        stra_conf.stra_inst_time[f'{stra_file}_{row[0]}_{row[1]}'] = row[2]
                    cursor.close()
                    conn.close()
                else:
                    stra_conf.cfg.pg_order.execute(
                        f"DELETE FROM public.strategy_sign WHERE strategy_group='{stra_file}'")
            with open(cfg_file, encoding='utf-8') as stra_cfg_file:
                params = yaml.load(stra_cfg_file, loader.FullLoader)
                for param in [p for p in params if p is not None]:  # 去除None的配置
                    stra: StraTmpl = c(param)
                    stra.ID = param['ID']
                    stra_conf.cfg.log.info(f"load strategy:{stra_file}, id:{param['ID']}")

                    for data in stra.Datas:
                        data.SingleOrderOneBar = stra_conf.cfg.single_order_one_bar
                    # 由atp处理策略指令
                    stra._data_order = stra_conf.on_order
                    stra_conf.stra_instances.append(stra)
        else:
            stra_conf.cfg.log.error(f"缺少对应的 yaml 配置文件{cfg_file}")
